package com.qdlc.p2p.dal.model.interest;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.qdlc.p2p.common.exception.BorrowException;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.DateUtil;

/**
 * 每月还息到期还本利息计算函数
 *
 * @version 1.1.0.0
 * @author:wuaj
 */
public class MonthlyInterestCalculator implements InterestCalculator {

    /** 借款金额 */
    private double account;

    /** 年利率 */
    private double yearApr;

    /** 利息管理费 */
    private double manageFee;

    /** 期数 */
    private int periods;

    /** 标记是否为满标复审 */
    private boolean flag;

    /** 还款金额 */
    private double repayAccount;

    /** 开始计息日 */
    private Date interestTime;

    /** 还款日 */
    private Date repayTime;

    /** 还款计划 */
    private List<EachPlan> eachPlanList;

    /**
     * 初始化每月还息到期还本构造函数
     *
     * @param account      借款金额
     * @param yearApr      年利率
     * @param interestTime 开始计息日
     * @param periods      期数
     * @param flag         ？？？
     * @param manageFee    利率管理费
     */
    public MonthlyInterestCalculator(double account, double yearApr, Date interestTime, int periods, boolean flag,
                                     double manageFee) {
        this.account = account;
        this.yearApr = yearApr;
        this.periods = periods;
        this.manageFee = manageFee;
        this.interestTime = interestTime;
        this.flag = flag;
        eachPlanList = new ArrayList<EachPlan>();
    }

    @Override
    public List<EachPlan> calculator() {
        // 如果是发标或复审或投标或网贷计算器则total = account; 否则total = BigDecimalUtil.mul(account, periods);
        double totalAmount = flag ? account : BigDecimalUtil.mul(account, periods);

        double monthApr = BigDecimalUtil.div(yearApr, 12); // 月利率
        // 月利息((总金额 * 月利率))
        double interest = BigDecimalUtil.decimal(BigDecimalUtil.mul(totalAmount, monthApr), 2);
        // 总利息(总金额 * 月利率 * 期数/月数) 比 月息 * 月份 多一点点
        double totalInterest = BigDecimalUtil.decimal(BigDecimalUtil.mul(interest, periods), 2);

        // 月净息(利息 * (1 - 管理费率))
        double netInterest = BigDecimalUtil.decimal(BigDecimalUtil.mul(interest, BigDecimalUtil.sub(1, manageFee)), 2);
        // 总净息(利息 * (1 - 管理费率))
        double netTotalInterest = BigDecimalUtil.decimal(BigDecimalUtil.mul(totalInterest, BigDecimalUtil.sub(1, manageFee)), 2);

        double sumInterest = 0; // 利息累加
        double sumNetInterest = 0; // 净利息累加

        EachPlan eachPlan = null;
        // 开始计息日 + 1
        Date startInterestTime = DateUtil.rollDay(interestTime, 1);
        for (int i = 0; i < periods; i++) {
            eachPlan = new EachPlan();
            // 每期还款即是本期的还款总额
            if (i == periods - 1) { // 判断是否是最后一期
                eachPlan.setCapital(account); // 本金
                eachPlan.setInterest(BigDecimalUtil.sub(totalInterest, sumInterest)); // 总利息 - 已累积利息
                eachPlan.setNetInterest(BigDecimalUtil.sub(netTotalInterest, sumNetInterest)); // 净总利息 - 已累积净利息
                eachPlan.setTotal(BigDecimalUtil.add(account,eachPlan.getInterest())); // 总额 = 本金 + 利息
                eachPlan.setNetTotal(BigDecimalUtil.add(account,eachPlan.getNetInterest())); // 净总额 = 本金 + 净利息
                eachPlan.setNeedRepay(0); // 未归还本息
            } else {
                sumInterest = BigDecimalUtil.add(sumInterest, interest);
                sumNetInterest = BigDecimalUtil.add(sumNetInterest, netInterest);

                eachPlan.setCapital(0); // 本金
                eachPlan.setInterest(interest); // 利息
                eachPlan.setNetInterest(netInterest); // 净利息
                eachPlan.setTotal(interest); // 总额 = 本金 + 利息
                eachPlan.setNetTotal(netInterest); // 净总额 = 本金 + 净利息
                // 总本金 + 总利息 - 已还利息
                eachPlan.setNeedRepay(BigDecimalUtil.add(totalAmount, BigDecimalUtil.sub(totalInterest, sumInterest))); // 未归还本息
            }
            eachPlan.setInterestTime(startInterestTime); // 计息开始时间
            eachPlan.setRepayTime(DateUtil.rollMon(startInterestTime, i + 1)); // 下个月
            eachPlanList.add(eachPlan);
        }
		// 汇总信息
		this.repayAccount = BigDecimalUtil.add(account, totalInterest) ;
        // 最后一期还款日
        repayTime = eachPlan.getRepayTime();
        return eachPlanList;
    }

    @Override
    public List<EachPlan> calculator(int days) {
        throw new BorrowException("每月还息到期还本不支持按天还款!", BorrowException.TYPE_JSON);
    }

    @Override
    public List<EachPlan> getEachPlanList() {
        return eachPlanList;
    }

    @Override
    public double repayTotal() {
        return this.repayAccount;
    }

    @Override
    public Date repayTime() {
        return repayTime;
    }

    @Override
    public Date calculatorRepayTime(Date date, int i) {
        return DateUtil.rollMon(date, i);
    }
}
